home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / resetsw.arc / EDISK2.ASM next >
Encoding:
Assembly Source File  |  1986-01-05  |  25.5 KB  |  561 lines

  1.  
  2. TITLE EDISK - INSTALLABLE DEVICE DRIVER FOR A HIGH MEMORY VIRTUAL DISK
  3. ;1/1/86
  4. ;    Added code to prompt for cold boot reinitialization for use
  5. ;    with hardware reset button.  This modification lets RAM disk
  6. ;    contents survive cold boot after system crash.
  7. ;11/10/85
  8. ;       This ram disk uses the 128K portion of memory above 640K be-
  9. ;       ginning at segment D000:0000 and ending at F000:0000.
  10. ;       The original code comes from the DOS 2.0 Technical Manual, later
  11. ;       modified by Rex McAnally to allow variable sizes. (I have
  12. ;       included his original notes below.)
  13. ;       The code has been modified in accordence with the POWER USER
  14. ;       column in PC Magazine, Oct. 15, 1985.  It includes the following
  15. ;       features:
  16. ;                a. It will assemble with both versions 1 & 2 MACRO
  17. ;                   Assenbler
  18. ;
  19. ;                b. The program initializes the 128K RAM to prevent the
  20. ;                   dreaded PARITY error (DOS won't do it)
  21. ;
  22. ;                c. The contents of the Ram disk will survive a warm boot
  23. ;                   (Ctl-Alt-Del)
  24. ;
  25. ;       You have to provide the 128K ram memory addressable at segment D000
  26. ;       Note: This 128K was reserved for ROM based programs like those found
  27. ;             for the PC jr.  None are available for the PC/PC-XT so the
  28. ;             memory space is normally unusable & wasted.  It can't be added
  29. ;             to DOS as it is'nt continuous with the 640K user's area.
  30. ;
  31. ;       The easiest way to add this memory to your PC is to buy an IBM
  32. ;       64/256K Memory Expansion Option board, install 128K on it, and
  33. ;       set its DIP switches for a start address of D000 like so:
  34. ;
  35. ;                 switch     1   2   3   4   5   6   7   8
  36. ;                 position  off off  on off off  on off off
  37. ;
  38. ;       Not all memory or combo memory boards will do.  Most don't allow
  39. ;       you to choose the absolute starting segment address.
  40. ;
  41. ;       To use this program:
  42. ;
  43. ;                1.  Assemble this program using the MACRO Assembler
  44. ;
  45. ;                2.  Link the resultant .OBJ file using LINK (DOS utility)
  46. ;
  47. ;                3.  Convert the resultant .EXE file to binary form using
  48. ;                    EXE2BIN (also a DOS utility), and name it EDISK.SYS
  49. ;
  50. ;                4.  Copy the EDISK.SYS file to your BOOT/Root directory
  51. ;
  52. ;                5.  Add DEVICE=EDISK.SYS as the **FIRST** line of your
  53. ;                    CONFIG.SYS file.  It   M-u-s-t  be first as the program
  54. ;                    has to know whether it sees a first or a subsequent
  55. ;                    Boot.  Some Devive drivers cause a double Boot and
  56. ;                    if they precede EDISK.SYS they will cause EDISK to
  57. ;                    think an initial cold Boot is a warm Boot.  This
  58. ;                    screws up the Ram Disk data preserve function and
  59. ;                    will most likely cause your system to hang up.
  60. ;
  61. ;       A driver that adds 64K above the 640K user area to DOS (IF you have
  62. ;       Ram there), such as MEMM.SYS works OK as long as it follows the EDISK
  63. ;       driver in CONFIG.SYS.
  64. ;
  65. ;       I have marked the lines I modified with  EM  and those I added
  66. ;       with  EM-A.  By now this code has been pretty well hacked and
  67. ;       could stand some cleaning up, but it works fine as is.  Feel free
  68. ;       to clean it up or improve it further.
  69. ;
  70. ;                         ENJOY,
  71. ;                                  Bill Wacker
  72. ;
  73. ;
  74. ;Rex McNally's unmodified notes follow:
  75. ;
  76. ;       This was originally the virtual disk device contained in
  77. ;       the DOS 2.0 manual (listing only).
  78. ;
  79. ;       The code has been modified to allow a ram disk of more than
  80. ;       180k.  This can be specified in 2 ways.
  81. ;       (1). Changing the RAMDISK equate statment to the desired size in
  82. ;              1 K increments, reassembling, linking, using EXE2BIN,
  83. ;              to convert to "com" file format. (see DOS 2.0 manual on
  84. ;              device drivers.
  85. ;       (2). Rename the "VDISK.COM" file to "VDISK.XXX",
  86. ;            Using DEBUG you can modify the size by changing offsets
  87. ;            29-30 hex in the file. offset 29 = low order byte, 30 = h/o
  88. ;            These 2 bytes contain the size in 1K increments.
  89. ;
  90. ;       The current maximum limit is 512K (0200 hex).
  91. ;
  92. ;       All modified lines of code have been labeled with <RM> comments.
  93. ;       Please feel free to play with this, I am considering enhancing it
  94. ;       to ask the operator for a size before completing the device
  95. ;       installation.
  96. ;       Rex McAnally
  97. ;
  98.               PAGE
  99. CSEG          SEGMENT PARA PUBLIC 'CODE'
  100. ;
  101. ;***              MACRO DEFINITIONS
  102. ;
  103. STATUS        MACRO    STATE,ERR,RC
  104.               IFIDN    <STATE>,<DONE>
  105.                 OR     ES:WORD PTR SRH_STA_FLD[BX],0100H
  106.               ENDIF
  107.               IFIDN    <STATE>,<BUSY>
  108.                 OR     ES:WORD PTR SRH_STA_FLD[BX],0200H
  109.               ENDIF
  110.               IFIDN    <ERR>,<ERROR>
  111.                 OR     ES:WORD PTR SRH_STA_FLD[BX],1000H
  112.               ENDIF
  113.               IFNB     <RC>
  114.                 OR     ES:WORD PTR SRH_STA_FLD[BX],RC
  115.               ENDIF
  116.               ENDM
  117. ;
  118. ;***Equates
  119. ;
  120. ;***Size
  121. ;
  122. SECT          EQU      512         ; size of a sector                  <RM>
  123. RAMDISK       EQU      128         ; size of ramdisk in 1k increments <RM> <EM>
  124. FATSIZE       EQU      1           ; # sect in 1 copy of fat           <RM>
  125. ;
  126. ;***Read/Write
  127. ;
  128. SRH           EQU      0           ;Static request header start
  129. SRH_LEN       EQU      13          ;  "       "      "    length
  130. SRH_LEN_FLD   EQU      SRH         ;  "       "      "    length field
  131. SRH_UCD_FLD   EQU      SRH+1       ;  "       "      "    unit code field
  132. SRH_CCD_FLD   EQU      SRH+2       ;  "       "      "    command code fld
  133. SRH_STA_FLD   EQU      SRH+3       ;  "       "      "    status field
  134. SRH_RES_FLD   EQU      SRH+5       ;  "       "      "    reserved area fld
  135. MD            EQU      SRH+SRH_LEN ;Media descriptor byte
  136. MD_LEN        EQU      1           ;  "       "        "  length
  137. DTA           EQU      MD+MD_LEN   ;Disk transfer address
  138. DTA_LEN       EQU      4           ;DTA length
  139. COUNT         EQU      DTA+DTA_LEN ;Byte/Sector count
  140. COUNT_LEN     EQU      2           ;      "       "   length
  141. SSN           EQU      COUNT+COUNT_LEN ;Starting sector number
  142. SSN_LEN       EQU      2               ;   "       "       "   length
  143. ;
  144. ;***Media check
  145. ;
  146. RET_BYTE      EQU      MD+MD_LEN   ;Byte returned from driver
  147. ;
  148. ;***Build BPB
  149. ;
  150. BPBA_PTR      EQU      DTA+DTA_LEN
  151. BPBA_PTA_LEN  EQU      4
  152. ;
  153. ;***Init
  154. ;
  155. UNITS         EQU      SRH+SRH_LEN
  156. UNITS_LEN     EQU      1
  157. BR_ADDR_0     EQU      UNITS+UNITS_LEN
  158. BR_ADDR_1     EQU      BR_ADDR_0+2
  159. BR_ADDR_LEN   EQU      4
  160. BPB_PTR_OFF   EQU      BR_ADDR_0+BR_ADDR_LEN
  161. BPB_PTR_SEG   EQU      BPB_PTR_OFF+2
  162. ;
  163. ;
  164. VDSK          PROC     FAR
  165.               ASSUME   CS:CSEG,ES:CSEG,DS:CSEG
  166. BEGIN:
  167. START         EQU      $
  168. ;
  169. ;***Special device header
  170. ;
  171. NEXT_DEV      DD       -1          ;Pointer to next device
  172. ATTRIBUTE     DW       2000H       ;Block device (NON-IBM FORMAT)
  173. STATEGY       DW       DEV_STATEGY ;Pointer to device stategy
  174. INTERRUPT     DW       DEV_INT     ;Pointer to device interrupt handler
  175. DEV_NAME      DB       1           ;Number of block devices
  176.               DB       7 DUP(?)    ;7 bytes of filler
  177. RH_OFF        DW       ?           ;Request header offset
  178. RH_SEG        DW       ?           ;Request header segment
  179. ;
  180. ;***BIOS parameter block
  181. ;
  182. BPB           EQU      $
  183.               DW       SECT                   ;Sector size             <RM>
  184.               DB       1                      ;Sectors/allocation unit
  185.               DW       1                      ;Number of reserved sectors
  186.               DB       2                      ;Number of FATS
  187.               DW       64                     ;# of directory entries  <RM>
  188. RAMSECT1      DW       256                    ;Total number of sectors     <EM>
  189.               DB       0FEH                   ;Media descriptor
  190. FATSIZE1      DW       FATSIZE                ;# of sectors used by FAT<RM>
  191. BPB_PTR       DW       BPB                    ;BIOS parameter blk ptr array
  192. ;
  193. ;***Current virtual disk information
  194. ;
  195.               DB       'SIZE'      ;                                   <RM>
  196. RAMSIZEK      DW       RAMDISK     ; size in 1k increments             <RM>
  197. RAMSIZEP      DW       RAMDISK*(1024/16)     ; size in paragraphs      <RM>
  198. ;
  199. TOTAL         DW       ?           ;Total sectors to transfer
  200. VERIFY        DB       0           ;Verify 1=YES, 0=NO
  201. START_SEC     DW       0           ;Starting sector number
  202. VDISK_PTR     DW       0           ;Starting sector of virtual disk
  203. USER_DTA      DW       ?,?         ;Pointer to callers DTA                <EM>
  204. BOOT_REC      EQU      $           ;Dummy DOS boot record
  205.               DB       3 DUP(0)    ;3 byte jump to boot code (not bootable)
  206.               DB       'IBM  2.0'
  207.               DW       SECT        ;Number of bytes in a sector        <RM>
  208.               DB       1           ;1 sector per allocation unit
  209.               DW       1           ;1 reserved sector
  210.               DB       2           ;2 FATS
  211.               DW       64          ;Number of directory entries
  212. RAMSECT2      DW       256                  ; total sectors in image  <RM><EM>
  213.               DB       0FEH        ;Single sided 9 sector
  214. FATSIZE2      DW       FATSIZE     ;Number of sectors in FAT           <RM>
  215. ;
  216. ;***Function table
  217. ;
  218. FUNTAB        LABEL    BYTE
  219.               DW       INIT        ;Initialization
  220.               DW       MEDIA_CHECK ;Media check (block only)
  221.               DW       BUILD_BPB   ;Build BPB
  222.               DW       IOCTL_IN    ;IOCTL input
  223.               DW       INPUT       ;Input (read)
  224.               DW       ND_INPUT    ;Non destructive input no wait (ch only)
  225.               DW       IN_STAT     ;Input status
  226.               DW       IN_FLUSH    ;Input flush
  227.               DW       OUTPUT      ;Output (write)
  228.               DW       OUT_VERIFY  ;Output (write) with verify
  229.               DW       OUT_STAT    ;Output status
  230.               DW       OUT_FLUSH   ;Output flush
  231.               DW       IOCTL_OUT   ;IOCTL output
  232. ;
  233. ;***Local procedures
  234. ;
  235. IN_SAVE       PROC     NEAR
  236.               MOV      AX,ES:WORD PTR DTA[BX] ;Save callers DTA
  237.               MOV      CS:USER_DTA,AX
  238.               MOV      AX,ES:WORD PTR DTA+2[BX]
  239.               MOV      CS:USER_DTA+2,AX
  240.               MOV      AX,ES:WORD PTR COUNT[BX]
  241.               XOR      AH,AH
  242.               MOV      CS:TOTAL,AX
  243.               RET
  244. IN_SAVE       ENDP
  245. ;
  246. ;
  247. CALC_ADDR     PROC     NEAR
  248.               MOV      AX,CS:START_SEC       ;Get starting sector number
  249.               MOV      CX,SECT/16            ;Move 512 to CX segment style
  250.               MUL      CX                    ;Multiply to get actual sector
  251.               MOV      DX,CS:VDISK_PTR       ;Get segment of virtual disk
  252.               ADD      DX,AX                 ;Add that seg to initial seg
  253.               MOV      DS,DX                 ;Save that as actual segment
  254.               XOR      SI,SI                 ;It's on a para boundary
  255.               MOV      AX,CS:TOTAL           ;Total # of sectors to read
  256.               MOV      CX,SECT               ;Bytes per sector         <RM>
  257.               MUL      CX                    ;Multiply to get copy length
  258.               OR       AX,AX                 ;Check for greater than 64K
  259.               JNZ      MOVE_IT
  260.               MOV      AX,0FFFFH             ;Move in for 64K
  261. MOVE_IT:      XCHG     CX,AX                 ;Move length to CX
  262.               RET
  263. CALC_ADDR     ENDP
  264.  
  265.  
  266. SECTOR_READ   PROC     NEAR
  267.               CALL     CALC_ADDR             ;Calculate the starting sector
  268.               MOV      ES,CS:USER_DTA+2      ;Set dest (ES:DI) to point
  269.               MOV      DI,CS:USER_DTA        ;**to callers DTA
  270. ;
  271. ;***Check for DTA wrap in case we came through via verify
  272. ;
  273.               MOV      AX,DI       ;Get offset of DTA
  274.               ADD      AX,CX       ;Add copy length to it
  275.               JNC      RC          ;Carry flag=0, no wrap
  276.               MOV      AX,0FFFFH   ;Max length
  277.               SUB      AX,DI       ;Subtract DTA offset from max
  278.               MOV      CX,AX       ;Use that as copy length to avoid wrap
  279. RC:     REP   MOVSB                ;Do the read
  280.               RET
  281. SECTOR_READ   ENDP
  282.  
  283.  
  284. SECTOR_WRITE  PROC     NEAR
  285.               CALL     CALC_ADDR              ;Calculate starting sector
  286.               PUSH     DS
  287.               POP      ES                     ;Establish addressability
  288.               MOV      DI,SI                  ;ES:DI point to disk
  289.               MOV      DS,CS:USER_DTA+2       ;DS:SI point to callers DTA
  290.               MOV      SI,CS:USER_DTA
  291. ;
  292. ;***Check for DTA wrap
  293. ;
  294.               MOV      AX,SI       ;Move DTA offset to AX
  295.               ADD      AX,CX       ;Add copy length to offset
  296.               JNC      WC          ;Carry flag=0, no segment wrap
  297.               MOV      AX,0FFFFH   ;Move in max copy length
  298.               SUB      AX,SI       ;Subtract DTA offset from max
  299.               MOV      CX,AX       ;Use as new copy length to avoid wrap
  300. WC:     REP   MOVSB                ;Do the write
  301.               RET
  302. SECTOR_WRITE  ENDP
  303.               PAGE
  304. ;
  305. ;***Device strategy
  306. ;
  307. DEV_STATEGY:  MOV      CS:RH_SEG,ES ;Save segment of request header ptr
  308.               MOV      CS:RH_OFF,BX ;Save offset of     "      "     "
  309.               RET
  310. ;
  311. ;***Device interrupt handler
  312. ;
  313. DEV_INT:      CLD
  314. ;
  315. ;***Save state of machine
  316. ;
  317.               PUSH     DS
  318.               PUSH     ES
  319.               PUSH     AX
  320.               PUSH     BX
  321.               PUSH     CX
  322.               PUSH     DX
  323.               PUSH     DI
  324.               PUSH     SI
  325. ;
  326. ;***Do branch according to function passed
  327. ;
  328.               MOV      AL,ES:[BX]+2          ;Get function byte
  329.               ROL      AL,1                  ;Get offset into table
  330.               LEA      DI,FUNTAB             ;Get address of function table
  331.               XOR      AH,AH
  332.               ADD      DI,AX
  333.               JMP      WORD PTR[DI]
  334. ;
  335. ;***Initialization
  336. ;
  337. INIT:
  338.               MOV      AX,CS:RAMSIZEK        ; compute size in # sect  <RM>
  339.               CMP      AX,171                ;                         <RM>
  340.               JB       INIT20                ;                         <RM>
  341.               MOV      CS:WORD PTR FATSIZE1,2 ;                        <RM>
  342.               MOV      CS:WORD PTR FATSIZE2,2 ;                        <RM>
  343.               CMP      AX,341                ;                         <RM>
  344.               JB       INIT20                ;                         <RM>
  345.               MOV      CS:WORD PTR FATSIZE1,3 ;                        <RM>
  346.               MOV      CS:WORD PTR FATSIZE2,3 ;                        <RM>
  347. INIT20:                                      ;                         <RM>
  348.               SHL      AX,1                  ;                         <RM>
  349.               MOV      CS:RAMSECT1,AX        ;                         <RM>
  350.               MOV      CS:RAMSECT2,AX        ;                         <RM>
  351.               MOV      CL,5                  ; compute size in paragr  <RM>
  352.               SHL      AX,CL                 ;                         <RM>
  353.               MOV      CS:RAMSIZEP,AX        ;                         <RM>
  354. ;                                                                      <RM>
  355.               PUSH     CS
  356.               POP      DX                    ;Current CS to DX
  357.               LEA      AX,CS:VDISK           ;Get address of virtual disk
  358.               MOV      CL,4
  359.               ROR      AX,CL                 ;Divide by 16 (paragraph form)
  360.               ADD      DX,AX                 ;Add to current CS value
  361.               MOV      CS:VDISK_PTR,0D000H   ;Save as start seg of vdisk   <EM>
  362.            ;  MOV      AX,CS:RAMSIZEP        ;Add size of vdisk in para<RM><EM>
  363.            ;  ADD      DX,AX                  ;**segment of virtual disk   <EM>
  364.               MOV      ES:WORD PTR BR_ADDR_0[BX],0
  365.               MOV      ES:BR_ADDR_1[BX],DX    ;Make that the break address
  366.               MOV      ES:BYTE PTR UNITS[BX],1 ;Number of diskette units
  367.               LEA      DX,BPB_PTR            ;Get addr of BPB ptr array
  368.               MOV      ES:BPB_PTR_OFF[BX],DX  ;Save offset in data packet
  369.               MOV      ES:BPB_PTR_SEG[BX],CS  ;Save segment in data packet
  370.  
  371.               PUSH     DS                     ;Save DS                   <EM-A>
  372.               MOV      AX,40H                 ;BIOS data segment         <EM-A>
  373.               MOV      DS,AX                  ;Set up segment register   <EM-A>
  374.               CMP      WORD PTR DS:[0072H],1234H  ;Check reset mode      <EM-A>
  375.               POP      DS                     ;Restore DS                <EM-A>
  376.               JNZ      COLD_START             ;Initialize Vdisk          <EM-A>
  377.               JMP      HOT_START              ;Skip if boot from keyboard<EM-A>
  378.  
  379.  
  380. COLD_START:          ; Initialize memory to avoid PARITY errors          <EM-A>
  381. ;/MCN addition: ask if ramdisk should be initialized at cold boot time
  382. ;Clobbers AX
  383.           PUSH     DS
  384.           PUSH     CS        ;Transfer CS to DS
  385.           POP      DS
  386.           LEA      DX,WHICH_MESS    ;Ramdisk clobber message
  387.           MOV      AH,9        ;Print string function
  388.           INT      21H
  389.           MOV      AH,1        ;Keyboard input function
  390.           INT      21H
  391.           POP      DS
  392.           CMP      AL,'Y'        ;If capital Y
  393.           JZ       COLD_CONT
  394.           CMP      AL,'y'        ;Or lower case y
  395.           JZ       COLD_CONT    ;Continue with cold start
  396.           JMP      HOT_START    ;Else treat as hot start
  397. WHICH_MESS:   DB       "Initialize Hi-RAM disk (y/n)?$"
  398. COLD_CONT:
  399. ;\MCN addition end
  400.               SUB      AX,AX                 ;Byte to write (null)       <EM-A>
  401.               MOV      ES,CS:VDISK_PTR       ;Get start addr of 1st 64K sector
  402.               MOV      CX,8000H              ;Number of bytes to write   <EM-A>
  403.               REP      STOSW                 ;Repeat no. of times in CX  <EM-A>
  404.               MOV      CX,ES                 ;Move to next sector by     <EM-A>
  405.               ADD      CX,1000H              ;adding 1000H to ES         <EM-A>
  406.               MOV      ES,CX                 ;New start addr at E000H    <EM-A>
  407.               MOV      CX,8000H              ;Reset CX counter to 8000H  <EM-A>
  408.               REP      STOSW                 ;Repeat write in second sect<EM-A>
  409.               MOV      ES,CS:VDISK_PTR       ;Restore addr to 1st seg    <EM-A>
  410.  
  411.               XOR      DI,DI                  ;Zero out DI (Boot record)
  412.               LEA      SI,BOOT_REC            ;Address of boot record
  413.               MOV      CX,24
  414.         REP   MOVSB                           ;Copy 24 bytes of boot record
  415.               MOV      CS:WORD PTR START_SEC,1
  416.               MOV      AX,FATSIZE1           ;                         <RM>
  417.               MOV      CS:WORD PTR TOTAL,AX  ;                         <RM>
  418.               CALL     CALC_ADDR              ;Calc addr of logical sect 1
  419.               PUSH     DS
  420.               POP      ES
  421.               MOV      DI,SI                  ;Move that address to ES:DI
  422.               XOR      AL,AL
  423.         REP   STOSB                           ;Zero out FAT area
  424.               MOV      DS:BYTE PTR[SI],0FEH   ;Set the first FAT entry
  425.               MOV      DS:BYTE PTR 1[SI],0FFH
  426.               MOV      DS:BYTE PTR 2[SI],0FFH
  427.               PUSH     DS                     ;Save pointer to FAT on
  428.               PUSH     SI                     ;**the stack
  429.               MOV      AX,CS:WORD PTR START_SEC ;                      <RM>
  430.               ADD      AX,CS:WORD PTR TOTAL     ;                      <RM>
  431.               MOV      CS:WORD PTR START_SEC,AX ;                      <RM>
  432. ;DEL          MOV      CS:WORD PTR TOTAL,2                             <RM>
  433.               CALL     CALC_ADDR              ;Calc addr of logical sect 3
  434.               PUSH     DS
  435.               POP      ES
  436.               MOV      DI,SI                  ;Move that address to ES:DI
  437.               POP      SI
  438.               POP      DS                     ;Restore addr of 1st entry
  439.         REP   MOVSB                           ;Copy first FAT to second FAT
  440.               MOV      AX,CS:WORD PTR START_SEC ;                      <RM>
  441.               ADD      AX,CS:WORD PTR TOTAL     ;                      <RM>
  442.               MOV      CS:WORD PTR START_SEC,AX ;                      <RM>
  443. ;DEL          MOV      CS:WORD PTR START_SEC,5                         <RM>
  444.               MOV      CS:WORD PTR TOTAL,4
  445.               CALL     CALC_ADDR              ;Calc addr of LS 5 (start dir
  446.               XOR      AL,AL
  447.               PUSH     DS
  448.               POP      ES                     ;Set up ES:DI to point to it
  449.               XOR      DI,DI
  450.         REP   STOSB                           ;Zero out directory
  451.               MOV      ES,CS:RH_SEG           ;Restore ES:BX to req header
  452.               MOV      BX,CS:RH_OFF
  453.               STATUS   DONE,NOERROR,0         ;Set status done (noerror)
  454.  
  455.               LEA      DX,COLD_MESSAGE        ;Choose initialize msg    <EM-A>
  456.               JMP      SHORT MESSAGE          ;Go display it            <EM-A>
  457. COLD_MESSAGE  DB       "Hi-RAM disk installed.",13,"$"        ;         <EM-A>
  458. HOT_MESSAGE   DB       "Hi RAM disk preserved.",13,"$"        ;         <EM-A>
  459. HOT_START:    LEA      DX,HOT_MESSAGE         ;Choose preserve msg      <EM-A>
  460. MESSAGE:      PUSH     CS                     ;Current segment          <EM-A>
  461.               POP      DS                     ;Set DS to it             <EM-A>
  462.               MOV      AH,9                   ;DOS print string call    <EM-A>
  463.               INT      21H                    ;Print the string         <EM-A>
  464.  
  465.               JMP      EXIT
  466. ;
  467. ;***Media check
  468. ;
  469. MEDIA_CHECK:  MOV      ES:BYTE PTR RET_BYTE[BX],1
  470.               STATUS   DONE,NOERROR,0         ;turn on the done bit
  471.               JMP      EXIT
  472. ;
  473. ;***Build BIOS parameter block
  474. ;
  475. BUILD_BPB:    PUSH     ES                     ;Save SRH segment
  476.               PUSH     BX                     ;Save SRH offset
  477.               MOV      CS:WORD PTR START_SEC,0
  478.               MOV      CS:WORD PTR TOTAL,1
  479.               CALL     CALC_ADDR             ;Calc addr of 1st sector
  480.               PUSH     CS
  481.               POP      ES
  482.               LEA      DI,BPB                 ;Addr of BIOS parameter block
  483.               ADD      SI,11
  484.               MOV      CX,13                  ;Length of BPB
  485.         REP   MOVSB
  486.               POP      BX                     ;Restore offset of SRH
  487.               POP      ES                     ;Restore segment of SRH
  488.               LEA      DX,BPB                 ;Get BPB array pointer
  489.               MOV      ES:BPBA_PTR[BX],DX     ;Save ptr to BPB table
  490.               MOV      ES:BPBA_PTR+2[BX],CS
  491.               MOV      ES:DTA[BX],DX          ;Offset to sector buffer
  492.               MOV      ES:DTA+2[BX],CS
  493.               STATUS   DONE,NOERROR,0
  494.               JMP      EXIT
  495. ;
  496. ;***The following entries are not supported by this device
  497. ;
  498. IOCTL_IN:
  499. IOCTL_OUT:
  500. ND_INPUT:                          ;Non destructive input no wait (ch only)
  501. IN_STAT:                           ;Input status      "     "
  502. IN_FLUSH:                          ;Input flush
  503. OUT_STAT:                          ;Output status
  504. OUT_FLUSH:                         ;Output flush
  505. ;
  506. ;***Disk read
  507. ;
  508. INPUT:        CALL     IN_SAVE                ;Call the initial save rtn
  509.               MOV      AX,ES:WORD PTR SSN[BX] ;Set starting sector number
  510.               MOV      CS:START_SEC,AX        ;Save starting sector number
  511.               MOV      AX,ES:WORD PTR COUNT[BX]
  512.               MOV      CS:TOTAL,AX            ;Save # sectors to transfer
  513.               CALL     SECTOR_READ            ;Read in that many sectors
  514.               MOV      BX,CS:RH_OFF           ;Restore ES:BX as req header
  515.               MOV      ES,CS:RH_SEG
  516.               STATUS   DONE,NOERROR,0         ;Set status word (done, noerr
  517.               JMP      EXIT
  518. ;
  519. ;***Disk write
  520. ;
  521. OUTPUT:       CALL     IN_SAVE                ;Output (write)
  522.               MOV      AX,ES:WORD PTR SSN[BX] ;Get starting sector number
  523.               MOV      CS:START_SEC,AX        ;Set    "        "      "
  524.               MOV      AX,ES:WORD PTR COUNT[BX]
  525.               MOV      CS:TOTAL,AX            ;Save total sectors to write
  526.               CALL     SECTOR_WRITE
  527.               MOV      BX,CS:RH_OFF           ;Restore ES:BX as req header
  528.               MOV      ES,CS:RH_SEG
  529.               CMP      CS:BYTE PTR VERIFY,0   ;Write verify set
  530.               JZ       NO_VERIFY              ;No, no write verify
  531.               MOV      CS:BYTE PTR VERIFY,0   ;Reset verify indicator
  532.               JMP      INPUT
  533. NO_VERIFY:    STATUS   DONE,NOERROR,0         ;Set status done, no error
  534.               JMP      EXIT
  535. OUT_VERIFY:   MOV      CS:BYTE PTR VERIFY,1   ;Set verify flag
  536.               JMP      OUTPUT                 ;Branch to output routine
  537. ;
  538. ;***Common exit
  539. ;
  540. EXIT:         POP      SI
  541.               POP      DI
  542.               POP      DX
  543.               POP      CX
  544.               POP      BX
  545.               POP      AX
  546.               POP      ES
  547.               POP      DS
  548.               RET
  549. ;
  550. ;
  551. E_O_P:
  552. ;***Macro to align the virtual disk on a paragraph boundary
  553. IF ($-START) MOD 16
  554. ORG           ($-START)+16-(($-START) MOD 16)
  555. ENDIF
  556. VDISK         EQU      $
  557. VDSK          ENDP
  558. CSEG          ENDS
  559.               END      BEGIN
  560.